package org.jetnuke.modules.weblinks;

import org.apache.log4j.Logger;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.VelocityContext;
import org.jetnuke.common.ActionForward;
import org.jetnuke.common.IAction;
import org.jetnuke.common.IAdminInfo;
import org.jetnuke.common.IModuleInfo;
import org.jetnuke.common.IUserInfo;
import org.jetnuke.dao.DataAccessDriver;
import org.jetnuke.dao.LinkLinkDAO;
import org.jetnuke.entities.LinksLinks;
import org.jetnuke.entities.LinksVoteData;
import org.jetnuke.util.JetUtil;

public class AddRating implements IAction {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(AddRating.class);

	int lid;

	String rating;

	String ratingcomments = "";

	public void setLid(int lid) {
		this.lid = lid;
	}

	public void setRating(String rating) {
		this.rating = rating;
	}

	public void setRatingcomments(String ratingcomments) {
		this.ratingcomments = ratingcomments;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.jetnuke.common.IAction#exec(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse,
	 *      org.apache.velocity.VelocityContext, org.jetnuke.common.IModuleInfo,
	 *      java.lang.String, org.jetnuke.common.IUserInfo,
	 *      org.jetnuke.common.IAdminInfo)
	 */
	public ActionForward exec(HttpServletRequest request,
			HttpServletResponse response, VelocityContext vc, IModuleInfo info,
			String op, IUserInfo ui, IAdminInfo ai) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("exec(HttpServletRequest, HttpServletResponse, VelocityContext, IModuleInfo, String, IUserInfo, IAdminInfo) - start"); //$NON-NLS-1$
		}

		boolean pass = true;
		int error = -1;

		if (rating.equals("--")) {
			pass = false;
			error = 0;
		}

		String ip = request.getRemoteAddr();
		if (ui != null) {
			String uname = ui.getUname();
			int count = DataAccessDriver.getInst().newLinkLinkDAO().countUser(
					lid, uname);
			if (count > 0) {
				pass = false;
				error = 1;
			}
			count = DataAccessDriver.getInst().newLinkVoteDataDAO().countUser(
					lid, uname);
			if (count > 0) {
				pass = false;
				error = 2;
			}

		} else {// anonymous

			GregorianCalendar gc = new GregorianCalendar();
			gc.add(Calendar.DATE, -1);
			int count = DataAccessDriver.getInst().newLinkVoteDataDAO()
					.countAnonymous(lid, ip, gc.getTime());
			if (count > 0) {
				pass = false;
				error = 3;
			}
		}
		if (pass) {
			int iRating = Integer.parseInt(rating);
			LinksVoteData vote = new LinksVoteData();
			if (ui != null)
				vote.setRATINGUSER(ui.getUname());
			else
				vote.setRATINGUSER("");
			vote.setRATINGLID(lid);
			vote.setRATING(iRating);
			vote.setRATINGHOSTNAME(ip);
			ratingcomments = ratingcomments.trim();
			vote.setRATINGCOMMENTS(ratingcomments);
			vote.setRATINGTIMESTAMP(new Date());
			DataAccessDriver.getInst().newLinkVoteDataDAO().addNew(vote);
			LinkLinkDAO ddm = DataAccessDriver.getInst().newLinkLinkDAO();
			// vote.save();
			LinksLinks link = ddm.retrieveByPK(lid);
			link.setTOTALVOTES(link.getTOTALVOTES() + 1);
			if (ratingcomments.length() > 0)
				link.setTOTALCOMMENTS(link.getTOTALCOMMENTS() + 1);
			double rate = calcRate(lid, 10);// TODO
			link.setLINKRATINGSUMMARY(rate);
			ddm.update(link);
			JetUtil.redirect(vc, response, request.getContextPath()
					+ "/do/web_links/votevalid");
		} else {

			JetUtil.redirect(vc, response, request.getContextPath()
					+ "/do/web_links/novalid?error=" + String.valueOf(error));
		}

		if (logger.isDebugEnabled()) {
			logger
					.debug("exec(HttpServletRequest, HttpServletResponse, VelocityContext, IModuleInfo, String, IUserInfo, IAdminInfo) - end"); //$NON-NLS-1$
		}
		return null;
	}

	private double calcRate(int lid1, int impact) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("calcRate(int, int) - start"); //$NON-NLS-1$
		}

		double finalRating = 0;
		List ls = DataAccessDriver.getInst().newLinkVoteDataDAO()
				.getByRatingLid(lid1);
		int totalVotes = ls.size();
		Iterator it = ls.iterator();
		int anonvotes = 0;

		int anonvoteval = 0;
		int regvoteval = 0;
		while (it.hasNext()) {
			LinksVoteData vote = (LinksVoteData) it.next();
			int ratingVote = vote.getRATING();
			String user = vote.getRATINGUSER();
			if (user == null || user.length() == 0) {
				anonvotes++;
				anonvoteval += ratingVote;
			} else {
				regvoteval += ratingVote;
			}
		}
		int regvotes = totalVotes - anonvotes;
		if (totalVotes > 0) {
			if (regvotes == 0) {// Only anon
				finalRating = anonvoteval * 1. / anonvotes;
			} else if (anonvotes == 0) { // Only reg
				finalRating = regvoteval * 1. / regvotes;
			} else {
				double avgRU = regvoteval * 1. / regvotes;
				double avgAU = anonvoteval * 1. / anonvotes;
				double impactRU = regvotes;
				double impactAU = anonvotes * 1. / impact;
				finalRating = ((avgRU * impactRU) + (avgAU * impactAU))
						/ (impactRU + impactAU);
			}
		}

		if (logger.isDebugEnabled()) {
			logger.debug("calcRate(int, int) - end"); //$NON-NLS-1$
		}
		return finalRating;
	}
}
